import React, { useState } from 'react';
import { Upload, Modal, message, Card, Row, Col, Typography, Space, Image, Button } from 'antd';
import type { UploadFile, UploadProps } from 'antd';
import type { RcFile, UploadRequestOption as RcCustomRequestOptions } from 'rc-upload/lib/interface';
import { PlusOutlined, ReloadOutlined } from '@ant-design/icons';
import myAxios from '../utils/request';

const { Title, Text, Link } = Typography;

/**
 * 图片上传页面
 * - 使用 Ant Design Upload 组件
 * - 通过自定义请求使用已封装的 axios 实例进行上传
 * - 与后端接口 POST http://localhost:8999/picture/upload 对接
 */
const ImageUploadPage: React.FC = () => {
    const [fileList, setFileList] = useState<UploadFile[]>([]);
    const [previewOpen, setPreviewOpen] = useState(false);
    const [previewImage, setPreviewImage] = useState<string>('');
    const [uploadedUrl, setUploadedUrl] = useState<string>('');
    const [uploading, setUploading] = useState<boolean>(false);

    /**
     * 将文件读取为 base64，供本地预览使用
     */
    const getBase64 = (file: RcFile): Promise<string> =>
        new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => resolve(reader.result as string);
            reader.onerror = (error) => reject(error);
        });

    /**
     * 上传前校验：仅允许图片，限制大小不超过 10MB（与后端配置保持一致）
     */
    const beforeUpload: UploadProps['beforeUpload'] = (file) => {
        const isImage = file.type.startsWith('image/');
        if (!isImage) {
            message.error('只能上传图片文件');
            return Upload.LIST_IGNORE;
        }
        const isLt10M = file.size / 1024 / 1024 < 10;
        if (!isLt10M) {
            message.error('图片大小需小于 10MB');
            return Upload.LIST_IGNORE;
        }
        return true;
    };

    /**
     * 自定义上传逻辑：使用已封装的 axios 实例，直连后端上传接口
     */
    const handleCustomRequest = async (options: RcCustomRequestOptions) => {
        const { file, onError, onProgress, onSuccess } = options;
        const formData = new FormData();
        formData.append('file', file as Blob);

        try {
            setUploading(true);
            const response = await myAxios.post(
                '/picture/upload',
                formData,
                {
                    headers: { 'Content-Type': 'multipart/form-data' },
                    onUploadProgress: (progressEvent) => {
                        if (progressEvent.total) {
                            const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
                            onProgress?.({ percent });
                        }
                    },
                },
            );

            // 后端直接返回可访问 URL（字符串）
            const url: string = response.data;
            setUploadedUrl(url);
            // 同步到文件列表，便于展示缩略图和可点击查看
            setFileList((list) =>
                list.map((f) => (f.uid === (options.file as RcFile).uid ? { ...f, status: 'done', url } : f)),
            );
            onSuccess?.(response.data as unknown as void);
            message.success('上传成功');
        } catch (e) {
            onError?.(e as Error);
            const maybeAxiosError = e as { response?: { data?: { message?: string } } };
            message.error(maybeAxiosError?.response?.data?.message || '上传失败');
        } finally {
            setUploading(false);
        }
    };

    /**
     * 预览大图
     */
    const handlePreview: UploadProps['onPreview'] = async (file) => {
        if (!file.url && !file.preview && file.originFileObj) {
            file.preview = await getBase64(file.originFileObj as RcFile);
        }
        setPreviewImage((file.url as string) || (file.preview as string));
        setPreviewOpen(true);
    };

    /**
     * 文件列表变化时更新状态
     */
    const handleChange: UploadProps['onChange'] = ({ fileList: newList }) => {
        setFileList(newList);
    };

    const uploadButton = (
        <div>
            <PlusOutlined />
            <div style={{ marginTop: 8 }}>上传</div>
        </div>
    );

    return (
        <Row justify="center" style={{ padding: 16 }}>
            <Col style={{ width: '800px' }}>
                <Card>
                    <Space direction="vertical" size={16} style={{ width: '600px' }}>
                        <div>
                            <Title level={4} style={{ marginBottom: 4 }}>图片上传</Title>
                            <Text type="secondary">支持图片格式，大小不超过 10MB</Text>
                        </div>

                        <Upload
                            name="file"
                            listType="picture-card"
                            maxCount={1}
                            accept="image/*"
                            fileList={fileList}
                            beforeUpload={beforeUpload}
                            customRequest={handleCustomRequest}
                            onChange={handleChange}
                            onPreview={handlePreview}
                            multiple={false}
                        >
                            {fileList.length >= 1 ? null : uploadButton}
                        </Upload>

                        <Space align="center">
                            <Button
                                icon={<ReloadOutlined />}
                                onClick={() => {
                                    setFileList([]);
                                    setUploadedUrl('');
                                }}
                                disabled={uploading}
                            >
                                重置
                            </Button>
                        </Space>

                        {uploadedUrl && (
                            <Space direction="vertical" size={8} style={{ width: '100%' }}>
                                <Text>上传成功，图片访问地址：</Text>
                                <Link href={uploadedUrl} target="_blank" rel="noreferrer">
                                    {uploadedUrl}
                                </Link>
                                <Image src={uploadedUrl} alt="uploaded" width={200} />
                            </Space>
                        )}
                    </Space>
                </Card>

                <Modal open={previewOpen} footer={null} onCancel={() => setPreviewOpen(false)}>
                    <img alt="预览" style={{ width: '100%' }} src={previewImage} />
                </Modal>
            </Col>
        </Row>
    );
};

export default ImageUploadPage;

